/*
 * codelogger.cpp
 *
 *  Created on: 2011-8-19
 *      Author: chenl
 *     Purpose:
 *        Note:
 */

#include "codelogger.h"
#include "common/protocol.h"
#include "common/common_magic.h"
#include "global.h"
#include <assert.h>
#include <string.h>

CCodeLogger::CCodeLogger() : m_nBuffOffset(0)
{
	memset(&m_buf, 0, sizeof(m_buf));
}

CCodeLogger::~CCodeLogger()
{

}

void CCodeLogger::DoPackageLog(const Byte *pszBuf, unsigned int uBufLen)
{
	//獲取數據包標誌位偏移
	uint32_t nOffset = find_pkg_header_byte(pszBuf);

	//非法數據包
	if ((0 != m_nBuffOffset && 0 == nOffset) || (0 == m_nBuffOffset && 0 != nOffset))
	{
		WRITE_MAIN_LOG(enmLogLevel_Error, "received invalid package!");
		Flush();
		goto NEXT_PKG;
	}

	//補完上一個不完整的數據包
	if (0 != m_nBuffOffset && 0 != nOffset)
	{
		if (nOffset + m_nBuffOffset > sizeof(m_buf))
		{
			WRITE_MAIN_LOG(enmLogLevel_Error, "received invalid package(part)!");
			++nOffset;
			Flush();
			goto NEXT_PKG;
		}
		memcpy(m_buf + m_nBuffOffset, pszBuf, nOffset);
		m_nBuffOffset += nOffset;
	}
	//包頭是否完整
	if (m_nBuffOffset < PACKED_PKG_HEADER_SIZE)
	{
		WRITE_MAIN_LOG(enmLogLevel_Debug, "receive incomplete package head!");
		return;
	}
	//從包頭解出消息長度
	int32_t nMsgLen = GET_PACKAGE_DATA_LEN(m_buf);
	if (0 >= nMsgLen || MAX_MSG_SIZE < nMsgLen) //FIXME: MAX_MSG_SIZE比緩衝區內的要大，想辦法獲得MAX_PACKED_MSG_SIZE
	{
		WRITE_MAIN_LOG(enmLogLevel_Error, "received invalid package!");
		Flush();
		goto NEXT_PKG;
	}
	//數據包是否完整
	if (nMsgLen + PACKED_PKG_HEADER_SIZE > m_nBuffOffset)
	{
		WRITE_MAIN_LOG(enmLogLevel_Debug, "receive incomplete package!");
		return;
	}
	else if (nMsgLen + PACKED_PKG_HEADER_SIZE < m_nBuffOffset)
	{
		WRITE_MAIN_LOG(enmLogLevel_Error, "received invalid package!");
		Flush();
	}
	else
	{
		DumpPackage(m_buf, m_nBuffOffset);
	}

NEXT_PKG:
	while (nOffset < uBufLen)
	{
		//獲取數據包標誌位偏移
		nOffset += find_pkg_header_byte(pszBuf + nOffset);
		//不足一個包頭
		if (nOffset + m_nBuffOffset + PACKED_PKG_HEADER_SIZE > uBufLen)
		{
			memcpy(m_buf + m_nBuffOffset, pszBuf + nOffset, nBufLen - nOffset);
			m_nBuffOffset += nBufLen - nOffset;
		}
		//獲取完整包頭
		else
		{
			memcpy(m_buf, pszBuf + nOffset, PACKED_PKG_HEADER_SIZE);
			m_nBuffOffset += PACKED_PKG_HEADER_SIZE;
			nOffset += PACKED_PKG_HEADER_SIZE;
		}
		//從包頭解出消息長度
		int32_t nMsgLen = GET_PACKAGE_DATA_LEN(m_buf);
		if (0 >= nMsgLen || MAX_MSG_SIZE < nMsgLen) //FIXME: MAX_MSG_SIZE比緩衝區內的要大，想辦法獲得MAX_PACKED_MSG_SIZE
		{
			WRITE_MAIN_LOG(enmLogLevel_Error, "received invalid package!");
			Flush();
			continue;
		}
		//不足一個數據包
		if (nOffset + PACKED_PKG_HEADER_SIZE + nMsgLen > uBufLen)
		{
			memcpy(m_buf + m_nBuffOffset, pszBuf + nOffset, uBufLen - nOffset);
			m_nBuffOffset += uBufLen - nOffset;
			nOffset += uBufLen - nOffset;
		}
		//數據包大小是否合法
		if (nOffset + PACKED_PKG_HEADER_SIZE + nMsgLen > sizeof(m_buf))
		{
			WRITE_MAIN_LOG(enmLogLevel_Error, "received invalid package!");
			++nOffset;
			Flush();
			continue;
		}
		//獲取完整數據包
		memcpy(m_buf + m_nBuffOffset, pszBuf + nOffset, nMsgLen);
		m_nBuffOffset += nMsgLen;
		nOffset += nMsgLen;
		DumpPackage(m_buf, m_nBuffOffset);
		Flush();

		return;
	}
}

void CCodeLogger::DumpPackage(const Byte *pszBuf, unsigned int uBufLen)
{
	ClientID id = enmInvalidClientID;
	Message	stMessage = {0};
	unsigned int uSizeofMsg = 0;
	int nOffset = 0;
	int ret = unpack_msg(pszBuf, uBufLen, nOffset, &id, &stMessage, &uSizeofMsg);
	if (0 > ret)
	{
		WRITE_MAIN_LOG(enmLogLevel_Error, "Receive invalid package!ret=0x%08X", ret);
		return;
	}
	CMessageWrapper messageWrapper(stMessage);
	WRITE_MAIN_LOG(enmLogLevel_Info, "Receive package from client(%d),size=%d,{%s}", id, uSizeofMsg, messageWrapper.Dump());
}

void CCodeLogger::Flush()
{
	m_nBuffOffset = 0;
#ifdef DEBUG
	memset(m_buf, DEBUF_MEM_MAGIC, sizeof(m_buf));
#endif
}
